package com.director.core;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Author: Simone Ricciardi
 * Date: 30-mag-2010
 * Time: 11.59.12
 */
public class DirectAction implements Serializable {

   private String namespace;
   private String name;
   private Class actionClass;
   private Map<String, DirectMethod> methods = new HashMap<String, DirectMethod>();

   public DirectAction(String namespace, String actionName, Class actionClass) {
      this.namespace = namespace;
      this.name = actionName;
      this.actionClass = actionClass;
   }

   public String getNamespace() {
      return namespace;
   }

   public String getName() {
      return this.name;
   }

   public Class getActionClass() {
      return this.actionClass;
   }

   public DirectMethod[] getMethods() {
      return this.methods.values().toArray(new DirectMethod[this.methods.size()]);
   }

   public boolean hasMethod(Method method) {
      for(DirectMethod directMethod : methods.values()) {
         if(directMethod.getMethod().equals(method)) {
            return true;
         }
      }
      return false;
   }

   DirectMethod addMethod(String methodName, Method method) {
      DirectMethod directActionMethod = new DirectMethod(methodName, method, this);
      this.methods.put(methodName, directActionMethod);
      return directActionMethod;
   }

   DirectTransactionResult invokeMethod(String methodName, DirectTransactionData data) throws DirectException {
      if(!this.methods.containsKey(methodName)) {
         String message = "No method found in action class '" + this.actionClass + "' with name '" + methodName + "'";
         throw new DirectException(message);
      }
      return this.methods.get(methodName).invoke(data);
   }

   @Override
   public boolean equals(Object o) {
      if(this == o) {
         return true;
      }
      if(!(o instanceof DirectAction)) {
         return false;
      }

      DirectAction that = (DirectAction) o;
      return this.name.equals(that.name);
   }

   @Override
   public int hashCode() {
      return this.name.hashCode();
   }

   @Override
   public String toString() {
      final StringBuilder sb = new StringBuilder();
      sb.append("DirectAction");
      sb.append("{name='").append(this.name).append('\'');
      sb.append(", actionClass=").append(this.actionClass);
      sb.append(", methods=").append(this.methods);
      sb.append('}');
      return sb.toString();
   }
}
